package com.xique.door.biz.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xique.common.core.domain.R;
import com.xique.common.core.utils.OrikaUtil;
import com.xique.common.core.utils.SecurityUtils;
import com.xique.common.core.utils.StringUtils;
import com.xique.common.core.web.domain.AjaxResult;
import com.xique.door.bean.dao.BuildHouseUserDAO;
import com.xique.door.bean.domain.*;
import com.xique.door.bean.request.AccessDevice.HouseSearchDeviceRequest;
import com.xique.door.bean.request.buildHouse.HouseClaimPageRequest;
import com.xique.door.bean.vo.house.HouseClaimListVO;
import com.xique.door.biz.service.IHouseClaimBizService;
import com.xique.door.command.IDeviceUserCommandService;
import com.xique.door.constant.HouseClaimConstant;
import com.xique.door.device.freeview.constant.CommandStatus;
import com.xique.door.service.*;
import com.xique.system.api.RemoteSystemUserService;
import com.xique.system.api.dto.OperateDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author shd
 * @create 2022/4/19 14:43
 */
@Service
public class HouseClaimBizServiceImpl implements IHouseClaimBizService {

    @Autowired
    private IHouseClaimService houseClaimService;

    @Autowired
    private IBuildAreaService areaService;

    @Autowired
    private IBuildBuildingService buildingService;

    @Autowired
    private IBuildHouseService houseService;

    @Autowired
    private RemoteSystemUserService remoteSystemUserService;

    @Autowired
    private IUserService userService;

    @Autowired
    private IBuildHouseUserService houseUserService;

    @Autowired
    private IAccessDeviceService accessDeviceService;

    @Autowired
    private IUserDeviceService userDeviceService;

    @Autowired
    private IDeviceUserCommandService deviceUserCommandService;

    @Override
    public AjaxResult getHouseClaimPage(HouseClaimPageRequest request) {

        request.setParkId(SecurityUtils.getParkId());

        Map<String, Object> map = new HashMap<>(2);
        map.put("list", new ArrayList<>());
        map.put("total", 0);

        IPage<HouseClaim> page = houseClaimService.selectHouseClaimPage(request);

        List<HouseClaim> list = page.getRecords();

        if (CollectionUtil.isEmpty(list)) {
            return AjaxResult.success(map);
        }

        List<HouseClaimListVO> vos = OrikaUtil.converts(list, HouseClaimListVO.class);

        // 获取区域信息
        List<Long> areaIds = list.stream().map(HouseClaim::getAreaId).distinct().collect(Collectors.toList());
        List<BuildAreaV1> areaList = areaService.listByIds(areaIds);
        Map<Long, String> areaMap = areaList.stream().collect(Collectors.toMap(BuildAreaV1::getId, BuildAreaV1::getAreaName));

        List<Long> buildingId = list.stream().map(HouseClaim::getBuildingId).distinct().collect(Collectors.toList());
        List<BuildBuildingV1> buildingList = buildingService.listByIds(buildingId);
        Map<Long, String> buildingMap = buildingList.stream().collect(Collectors.toMap(BuildBuildingV1::getId, BuildBuildingV1::getBuildingName));

        List<Long> houseIds = list.stream().map(HouseClaim::getHouseId).distinct().collect(Collectors.toList());
        List<BuildHouseV1> houseList = houseService.listByIds(houseIds);
        Map<Long, String> houseMap = houseList.stream().collect(Collectors.toMap(BuildHouseV1::getId, BuildHouseV1::getHouseName));

        List<Long> operateIds = list.stream().map(HouseClaim::getUpdateBy).distinct().collect(Collectors.toList());
        R<List<OperateDTO>> result = remoteSystemUserService.getOperateList(StringUtils.join(operateIds, ","));
        List<OperateDTO> operateList = result.getData();
        Map<Long, String> operateMap = operateList.stream().collect(Collectors.toMap(OperateDTO::getOperateId, OperateDTO::getOperateName));

        vos.forEach(item -> {
            if (StringUtils.isNotEmpty(areaMap.get(item.getAreaId()))) {
                item.setAreaName(areaMap.get(item.getAreaId()));
            }
            if (StringUtils.isNotEmpty(buildingMap.get(item.getBuildingId()))) {
                item.setBuildingName(buildingMap.get(item.getBuildingId()));
            }
            if (StringUtils.isNotEmpty(houseMap.get(item.getHouseId()))) {
                item.setHouseName(houseMap.get(item.getHouseId()));
            }
            if (StringUtils.isNotEmpty(operateMap.get(item.getUpdateBy()))) {
                item.setOperateName(operateMap.get(item.getUpdateBy()));
            }
        });

        map.put("list", vos);
        map.put("total", page.getTotal());

        return AjaxResult.success(map);
    }

    @Override
    public AjaxResult passHouseClaim(Long id) {

        /**
         * 1.更新审核表
         * 2.判断当前项目是否存在用户 不存在 则新增
         * 3.绑定用户跟房屋
         * 4.下发到设备
         * **/
        HouseClaim claim = houseClaimService.getById(id);
        if (StringUtils.isNull(claim)) {
            return AjaxResult.error("未找到对应记录");
        }
        if (!HouseClaimConstant.Status.WAITING.equals(claim.getStatus())) {
            return AjaxResult.error("该记录不处于待审核状态");
        }
        Long baseUserId = claim.getBaseUserId();
        User userSearch = new User();
        userSearch.setParkId(claim.getParkId());
        userSearch.setBaseUserId(baseUserId);
        List<User> userList = userService.selectUserList(userSearch);
        if (userList.size() > 1) {
            return AjaxResult.error("用户重复，请先去用户列表处理");
        }
        if (CollectionUtil.isEmpty(userList)) {
            // 新增用户
            User user = new User();
            user.setBaseUserId(baseUserId);
            user.setParkId(claim.getParkId());
            user.setUserName(claim.getUserName());
            user.setGender(claim.getGender().toString());
            user.setPhone(claim.getPhone());
            user.setIdentityType(claim.getIdentityType().toString());
            user.setFaceUrl(claim.getFaceUrl());
            user.setFaceKey(claim.getFaceKey());
            user.setUserType(0);
            userService.insertUser(user);
            userList.add(user);
        }
        User user = userList.get(0);
        user.setFaceUrl(claim.getFaceUrl());
        user.setFaceKey(claim.getFaceKey());

        List<BuildHouseUserDAO> houseUserDAOList = houseUserService.selectBuildHouseUserByUserIdAndHouseId(user.getId(), claim.getHouseId());
        if (CollectionUtil.isNotEmpty(houseUserDAOList)) {
            return AjaxResult.error("该用户已经绑定此房屋，无需重复添加");
        }

        User update = new User();
        update.setId(user.getId());
        update.setFaceUrl(claim.getFaceUrl());
        update.setFaceKey(claim.getFaceKey());
        update.setUserName(claim.getUserName());
        update.setGender(claim.getGender().toString());
        if (StringUtils.isNull(user.getBaseUserId())) {
            update.setBaseUserId(baseUserId);
        }
        update.setUserType(0);
        userService.updateUser(update);

        BuildHouseUser houseUser = new BuildHouseUser();
        houseUser.setHouseId(claim.getHouseId());
        houseUser.setBuildingId(claim.getBuildingId());
        houseUser.setUserId(user.getId());
        houseUser.setUserName(claim.getUserName());
        houseUser.setIdentityType(claim.getIdentityType().toString());
        BuildHouseV1 house = houseService.getById(claim.getHouseId());
        houseUser.setHouseName(house.getHouseName());
        BuildBuildingV1 building = buildingService.getById(claim.getBuildingId());
        houseUser.setBuildingName(building.getBuildingName());

        houseUserService.insertBuildHouseUser(houseUser);

        HouseSearchDeviceRequest houseSearchDeviceRequest = new HouseSearchDeviceRequest();
        houseSearchDeviceRequest.setHouseId(claim.getHouseId());
        List<AccessDevice> accessDevices = accessDeviceService.selectAccessDevicesByHouseIds(houseSearchDeviceRequest);
        if (CollectionUtil.isNotEmpty(accessDevices)) {
            List<UserDevice> userDevices = new ArrayList<>();
            for (AccessDevice accessDevice : accessDevices) {
                UserDevice userDevice = new UserDevice();
                userDevice.setParkId(user.getParkId());
                userDevice.setModel(accessDevice.getModel());
                userDevice.setUserId(user.getId());
                userDevice.setDeviceId(accessDevice.getId());
                userDevice.setDevSn(accessDevice.getDevSn());
                if (StringUtils.isEmpty(accessDevice.getOnlineStatus()) || "offline".equals(accessDevice.getOnlineStatus())) {
                    userDevice.setStatus(CommandStatus.PENDING);
                } else {
                    if (StringUtils.isNotEmpty(user.getFaceUrl())) {
                        userDevice.setStatus(CommandStatus.SEND);
                    } else {
                        userDevice.setStatus(CommandStatus.NOFACE);
                    }
                }
                userDevice.setCustomId(user.getCustomId());
                userDevice.setCreateBy(String.valueOf(SecurityUtils.getUserId()));
                userDevices.add(userDevice);
            }
            int i = userDeviceService.batchInsertUserDevice(userDevices);
            //step3: 下发
            if (StringUtils.isNotEmpty(user.getFaceUrl())) {
                //照片不为空才下发
                deviceUserCommandService.downDevicesUsers(accessDevices, Collections.singletonList(user));
            }
        }

        HouseClaim claimUpdate = new HouseClaim();
        claimUpdate.setId(id);
        claimUpdate.setStatus(HouseClaimConstant.Status.PASS);
        claimUpdate.setUpdateBy(SecurityUtils.getUserId());

        boolean isSuccess = houseClaimService.updateById(claimUpdate);
        if (!isSuccess) {
            return AjaxResult.error();
        }

        return AjaxResult.success();
    }

    @Override
    public AjaxResult rejectHouseClaim(Long id) {

        HouseClaim claim = houseClaimService.getById(id);
        if (StringUtils.isNull(claim)) {
            return AjaxResult.error("未找到对应记录");
        }
        if (!HouseClaimConstant.Status.WAITING.equals(claim.getStatus())) {
            return AjaxResult.error("该记录不处于待审核状态");
        }

        HouseClaim update = new HouseClaim();
        update.setId(id);
        update.setStatus(HouseClaimConstant.Status.REJECT);
        update.setUpdateBy(SecurityUtils.getUserId());

        boolean isSuccess = houseClaimService.updateById(update);
        if (!isSuccess) {
            return AjaxResult.error();
        }

        return AjaxResult.success();
    }
}
